#include <math.h>
#include <string.h>
#include "bezier.h"

int cg_fact(int n)
{
    int i, f = 1;
    for (i = 2; i <= n; i++)
	f *= i;
    return f;
}

double cg_bernstein(int n, int i, double t)
{
    return cg_fact(n) / (cg_fact(i) * cg_fact(n - i)) * pow(t, i) * pow(1 - t, n - i);
}

void cg_bezier_eval(double *dest, double u, double w, cgPoint **b, int s)
{
    int i, j;
    double coeff, bj, kj;
    memset(dest, 0, 3*sizeof(double));
    for (i = 0; i < s; i++)
	for (j = 0; j < s; j++)	{
	    bj = cg_bernstein(s-1, i, u);
	    kj = cg_bernstein(s-1, j, w);
	    coeff = bj * kj;
	    dest[0] += coeff * b[i][j].c[0];
	    dest[1] += coeff * b[i][j].c[1];
	    dest[2] += coeff * b[i][j].c[2];
	}
}

void cg_bezier_grid(cgPoint **dest, cgPoint **src, int s)
{
    int n = s * 5;
    double step = 1.0 / n;
    int i, j;
    
    for (i = 0; i < n; i++)
	for (j = 0; j < n; j++)
	    cg_bezier_eval(dest[i][j].c, i*step, j*step, src, s);
}
